<template>
  <div class="app-container">
    <!-- 侧边栏 -->
    <div class="sidebar">
      <div class="sidebar-header">AI助手平台</div>
      <div class="tabs">
        <div
          class="tab"
          :class="{ active: activeTab === 'assistants' }"
          @click="switchTab('assistants')"
        >
          <a
            href="#"
            @click.prevent
            style="color: inherit; text-decoration: none; display: block"
            >助手</a
          >
        </div>
        <div
          class="tab"
          :class="{ active: activeTab === 'sessions' }"
          @click="switchTab('sessions')"
        >
          <a
            href="#"
            @click.prevent
            style="color: inherit; text-decoration: none; display: block"
            >会话</a
          >
        </div>
      </div>

      <!-- 助手列表 -->
      <div class="tab-content" v-show="activeTab === 'assistants'">
        <div
          v-for="assistant in assistants"
          :key="assistant.id"
          class="assistant-item"
          :class="{ selected: selectedAssistant === assistant.id }"
          @click="selectAssistant(assistant.id)"
        >
          {{ assistant.name }}
        </div>
      </div>

      <!-- 会话列表 -->
      <div class="tab-content" v-show="activeTab === 'sessions'">
        <div class="session-actions">
          <button
            class="new-session-btn"
            @click="createNewSession"
            title="创建新会话"
          >
            <i class="fas fa-plus"></i>
          </button>
          <button
            class="control-button"
            @click="exportSessions"
            title="导出会话"
          >
            <i class="fas fa-download"></i>
          </button>
          <button
            class="control-button"
            @click="clearAllSessions"
            title="清空所有会话"
          >
            <i class="fas fa-trash"></i>
          </button>
        </div>
        <ul class="session-list">
          <li
            v-for="session in sessions"
            :key="session.id"
            class="session-item"
            :class="{ active: currentSessionId === session.id }"
            @click="switchSession(session.id)"
          >
            <div style="flex: 1; overflow: hidden">
              <div
                style="
                  font-weight: 500;
                  margin-bottom: 2px;
                  white-space: nowrap;
                  overflow: hidden;
                  text-overflow: ellipsis;
                "
              >
                {{ session.title || '新会话' }}
              </div>
              <div style="font-size: 12px; color: #666">
                {{ formatSessionTime(session.updatedAt) }}
              </div>
            </div>
            <button
              class="delete-session-btn"
              title="删除会话"
              @click.stop="deleteSession(session.id)"
            >
              <i class="fas fa-times"></i>
            </button>
          </li>
        </ul>
      </div>

      <!-- 知识库管理按钮 -->
      <div style="padding: 15px; border-top: 1px solid #e1e8ed">
        <button
          class="control-button"
          @click="goToKnowledgeBaseManager"
          style="
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
          "
        >
          <i class="fas fa-database"></i>
          知识库管理
        </button>
      </div>
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
      <div class="chat-container">
        <!-- 聊天消息区域 -->
        <div class="chat-messages" ref="chatMessages">
          <div
            v-for="message in messages"
            :key="message.id"
            class="message"
            :class="message.sender === 'user' ? 'user-message' : 'ai-message'"
          >
            <div class="message-header">
              <i
                class="fas"
                :class="message.sender === 'user' ? 'fa-user' : 'fa-robot'"
              ></i>
              {{ message.sender === 'user' ? '您' : '智能助手' }}
            </div>
            <div
              class="message-content"
              v-html="renderMarkdown(message.content)"
            ></div>

            <!-- AI消息的操作按钮 -->
            <div v-if="message.sender !== 'user'" class="message-actions">
              <button
                class="icon-button"
                title="复制回答内容"
                @click="copyToClipboard(message.content)"
              >
                <i class="fas fa-copy"></i>
              </button>
              <button
                class="icon-button"
                title="下载回答内容"
                @click="showExportModal(message.content)"
              >
                <i class="fas fa-download"></i>
              </button>
              <button
                v-if="message.sender === 'ai'"
                @click="deleteMessage(message.id)"
                class="delete-btn"
                title="删除回答"
              >
                <i class="fas fa-trash-alt"></i>
              </button>
            </div>
          </div>

          <!-- 正在输入的消息 -->
          <div v-if="isTyping" class="message ai-message">
            <div class="message-header">
              <i class="fas fa-robot"></i> 智能助手
            </div>
            <div class="message-content">
              <span class="typing-animation"
                >正在思考中<span>.</span><span>.</span><span>.</span></span
              >
            </div>
          </div>
        </div>

        <!-- 聊天输入区域 -->
        <div class="chat-input">
          <div class="text-area-container">
            <textarea
              v-model="question"
              placeholder="在这里输入消息，按Ctrl+Enter发送..."
              @keydown.ctrl.enter="sendQuestion"
              @keydown.meta.enter="sendQuestion"
            ></textarea>

            <!-- 文件列表 -->
            <div v-if="selectedFiles.length > 0" class="file-list-container">
              <div class="file-list-header">已选择的文件</div>
              <div class="file-list-items">
                <div
                  v-for="(file, index) in selectedFiles"
                  :key="index"
                  class="file-item"
                >
                  <span class="file-name">📎 {{ file.name }}</span>
                  <button
                    type="button"
                    class="delete-file-btn"
                    @click="deleteFile(index)"
                  >
                    <i class="fas fa-times"></i>
                  </button>
                </div>
              </div>
            </div>
          </div>

          <div class="input-controls">
            <!-- 知识库选择 -->
            <div
              class="dropdown-container"
              :class="{ active: openDropdown === 'knowledgeBase' }"
            >
              <div
                class="dropdown-button"
                @click.stop="toggleDropdown('knowledgeBase')"
              >
                {{ getKnowledgeBaseName(knowledgeBase) }}
              </div>
              <div class="dropdown-content" @click="preventClose">
                <div
                  v-for="kb in knowledgeBases"
                  :key="kb.id"
                  class="dropdown-item"
                  @click.stop="selectKnowledgeBase(kb.id, kb.name)"
                >
                  {{ kb.name }}
                </div>
              </div>
            </div>

            <!-- 大语言模型选择 -->
            <div
              class="dropdown-container"
              :class="{ active: openDropdown === 'llmModel' }"
            >
              <div
                class="dropdown-button"
                @click.stop="toggleDropdown('llmModel')"
              >
                {{ getModelName(llmModel) }}
              </div>
              <div class="dropdown-content" @click="preventClose">
                <div
                  v-for="model in llmModels"
                  :key="model.value"
                  class="dropdown-item"
                  @click.stop="selectModel(model.value, model.label)"
                >
                  {{ model.label }}
                </div>
              </div>
            </div>

            <!-- 搜索方式选择 -->
            <div
              class="dropdown-container"
              :class="{ active: openDropdown === 'searchMode' }"
            >
              <div
                class="dropdown-button"
                @click.stop="toggleDropdown('searchMode')"
              >
                {{ getSearchModeName(searchMode) }}
              </div>
              <div class="dropdown-content" @click="preventClose">
                <div
                  v-for="mode in searchModes"
                  :key="mode.value"
                  class="dropdown-item"
                  @click.stop="selectSearchMode(mode.value, mode.label)"
                >
                  {{ mode.label }}
                </div>
              </div>
            </div>

            <!-- 右侧功能按钮组 -->
            <div class="function-buttons">
              <button
                class="control-button"
                @click="clearWindow"
                title="清空窗口"
              >
                <i class="fas fa-trash-alt"></i>
              </button>
              <button
                class="control-button"
                @click="clearContext"
                title="清除上下文"
              >
                <i class="fas fa-sync-alt"></i>
              </button>
              <label for="file-upload" class="upload-button" title="上传文档">
                <i class="fas fa-file-upload"></i>
              </label>
              <input
                type="file"
                id="file-upload"
                class="file-upload"
                multiple
                @change="handleFileUpload"
              />
              <button
                class="send-button"
                @click="sendQuestion"
                title="发送消息"
              >
                <i class="fas fa-paper-plane"></i>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 复制成功提示 -->
    <div
      id="copy-success-toast"
      class="copy-success-toast"
      :class="{ show: showCopyToast }"
    >
      复制内容成功
    </div>

    <!-- 导出格式选择模态框 -->
    <div
      id="export-format-modal"
      class="modal"
      v-if="showExportModalFlag"
      @click="closeExportModal"
    >
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3 class="modal-title">选择导出格式</h3>
          <button class="close-btn" @click="closeExportModal">&times;</button>
        </div>
        <div class="format-options">
          <div class="format-option">
            <input
              type="radio"
              id="format-pdf"
              name="export-format"
              value="pdf"
              v-model="exportFormat"
            />
            <label for="format-pdf">PDF 格式</label>
          </div>
          <div class="format-option">
            <input
              type="radio"
              id="format-md"
              name="export-format"
              value="md"
              v-model="exportFormat"
            />
            <label for="format-md">Markdown 格式</label>
          </div>
          <div class="format-option">
            <input
              type="radio"
              id="format-doc"
              name="export-format"
              value="docx"
              v-model="exportFormat"
            />
            <label for="format-doc">Word 文档格式</label>
          </div>
        </div>
        <div class="modal-footer">
          <button class="modal-btn confirm-btn" @click="confirmExport">
            确认导出
          </button>
          <button class="modal-btn cancel-btn" @click="closeExportModal">
            取消
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import marked from 'marked'

export default {
  name: 'Chat',
  data() {
    return {
      // 标签切换
      activeTab: 'assistants',
      selectedAssistant: 'document',

      // 会话管理
      sessions: [],
      currentSessionId: null,
      currentSession: null,
      messages: [
        {
          id:
            'session_' +
            Date.now() +
            '_' +
            Math.random().toString(36).substr(2, 9),
          content:
            '您好！我是您的文档撰写助手。请选择一个知识库，然后输入您的问题。',
          sender: 'ai',
          timestamp: new Date().toISOString(),
        },
      ],

      // 输入相关
      question: '',
      selectedFiles: [],

      // 下拉菜单
      openDropdown: null,
      knowledgeBase: 'default',
      knowledgeBaseName: '知识库选择',
      knowledgeBases: [],
      llmModel: 'deepseek-v3',
      modelName: '模型选择',
      llmModels: [
        { value: 'deepseek-v3', label: 'DeepSeek-V3' },
        { value: 'qwen-7b', label: 'Qwen-7B' },
        { value: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo' },
      ],
      searchMode: 'deep_search',
      searchModeName: '深度搜索',
      searchModes: [
        { value: 'deep_search', label: '深度搜索' },
        { value: 'local_search', label: '本地搜索' },
      ],

      // 助手列表
      assistants: [
        { id: 'document', name: '文档辅助撰写助手' },
        { id: 'agent', name: '智能体助手' },
      ],

      // UI状态
      isTyping: false,
      showCopyToast: false,
      showExportModalFlag: false,
      exportFormat: 'pdf',
      exportContent: '',
    }
  },

  created() {
    this.init()
    // 点击页面其他区域关闭下拉菜单
    document.addEventListener('click', this.closeAllDropdowns)
  },

  destroyed() {
    document.removeEventListener('click', this.closeAllDropdowns)
  },

  methods: {
    // 初始化
    async init() {
      await this.loadSessions()
      if (this.sessions.length === 0) {
        await this.createNewSession()
      } else {
        this.currentSessionId = this.sessions[0].id
        this.currentSession = this.sessions[0]
        this.renderMessages()
      }
      await this.loadKnowledgeBases()
    },

    // 加载会话
    async loadSessions() {
      try {
        const response = await this.$http.get('/api/sessions')
        this.sessions = response || []
      } catch (error) {
        console.error('加载会话失败:', error)
        this.sessions = []
      }
    },

    // 创建新会话
    async createNewSession() {
      const sessionId = this.generateSessionId()
      const newSession = {
        id: sessionId,
        title: '新会话',
        messages: [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      }

      try {
        await this.$http.post('/api/sessions', newSession)
        this.sessions.unshift(newSession)
        this.currentSessionId = sessionId
        this.currentSession = newSession
        this.clearMessages()
      } catch (error) {
        console.error('创建会话失败:', error)
        this.$message.error('创建会话失败')
      }
    },

    // 删除消息
    async deleteMessage(messageId) {
      this.$confirm('确定要删除这条回答内容吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        closeOnClickModal: false,
      })
        .then(async () => {
          try {
            // 在本地数组中查找并删除消息
            const messageIndex = this.messages.findIndex(
              (m) => m.id === messageId
            )
            if (messageIndex !== -1) {
              this.messages.splice(messageIndex, 1)
            }

            // 更新会话数据
            if (this.currentSession) {
              const sessionIndex = this.sessions.findIndex(
                (s) => s.id === this.currentSessionId
              )
              if (sessionIndex !== -1) {
                const sessionMessageIndex = this.sessions[
                  sessionIndex
                ].messages.findIndex((m) => m.id === messageId)
                if (sessionMessageIndex !== -1) {
                  this.sessions[sessionIndex].messages.splice(
                    sessionMessageIndex,
                    1
                  )

                  // 更新会话更新时间
                  this.sessions[sessionIndex].updatedAt =
                    new Date().toISOString()

                  // 保存到数据库
                  await this.$http.post(
                    '/api/sessions',
                    this.sessions[sessionIndex]
                  )
                }
              }
            }
          } catch (error) {
            console.error('删除消息失败:', error)
            this.$message.error('删除消息失败')
          }
        })
        .catch(() => {
          this.$message.info('已取消删除')
        })
    },

    // 添加消息到会话
    async addMessageToSession(
      content,
      sender,
      renderNow = true,
      saveToBackend = true
    ) {
      if (!this.currentSessionId) {
        await this.createNewSession()
      }

      // 为每个消息生成唯一的ID，避免渲染重复
      const messageId =
        'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
      const timestamp = new Date().toISOString()

      const message = {
        id: messageId,
        content: content,
        sender: sender,
        timestamp: timestamp,
      }

      // 更新当前会话
      const session = this.sessions.find((s) => s.id === this.currentSessionId)
      if (session) {
        // 改进的重复消息检查 - 使用内容和时间窗口双重检查
        const duplicateIndex = session.messages.findIndex(
          (m) =>
            m.sender === sender &&
            m.content === content &&
            Math.abs(new Date(m.timestamp) - new Date(timestamp)) < 2000
        )

        if (duplicateIndex === -1) {
          session.messages.push(message)
        } else {
          // 如果是重复消息，更新时间戳和ID但不添加新消息
          session.messages[duplicateIndex].timestamp = timestamp
          session.messages[duplicateIndex].id = messageId

          if (renderNow) {
            // 在messages数组中也更新对应消息
            const messagesIndex = this.messages.findIndex(
              (m) =>
                m.sender === sender &&
                m.content === content &&
                Math.abs(new Date(m.timestamp) - new Date(timestamp)) < 2000
            )
            if (messagesIndex !== -1) {
              this.messages[messagesIndex].timestamp = timestamp
              this.messages[messagesIndex].id = messageId
            }
          }
          return // 不继续执行后面的代码
        }

        // 如果是第一条用户消息，更新会话标题
        if (
          sender === 'user' &&
          session.messages.filter((m) => m.sender === 'user').length === 1
        ) {
          session.title =
            content.length > 30 ? content.substring(0, 30) + '...' : content
        }

        session.updatedAt = new Date().toISOString()

        // 只在需要保存到后端时才调用API
        if (saveToBackend) {
          try {
            await this.$http.post('/api/sessions', session)
          } catch (error) {
            console.error('保存消息出错:', error)
            this.$message.error('保存消息失败')
          }
        }

        // 无论是否保存到后端，都更新本地消息显示
        if (renderNow) {
          // 再次检查是否已存在相同消息
          const exists = this.messages.some(
            (m) =>
              m.sender === sender &&
              m.content === content &&
              Math.abs(new Date(m.timestamp) - new Date(timestamp)) < 2000
          )

          if (!exists) {
            this.messages.push(message)
            this.scrollToBottom()
          }
        }
      }
    },

    // 切换会话
    async switchSession(sessionId) {
      const session = this.sessions.find((s) => s.id === sessionId)
      if (session) {
        this.currentSessionId = sessionId
        this.currentSession = session
        this.renderMessages()
      }
    },

    // 删除会话
    async deleteSession(sessionId) {
      if (this.sessions.length <= 1) {
        this.$message.warning('至少保留一个会话')
        return
      }

      this.$confirm('确定要删除这个会话吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        closeOnClickModal: false,
      })
        .then(async () => {
          try {
            await this.$http.delete(`/api/sessions/${sessionId}`)
            const index = this.sessions.findIndex((s) => s.id === sessionId)
            this.sessions.splice(index, 1)

            if (this.currentSessionId === sessionId) {
              this.currentSessionId = this.sessions[0].id
              this.currentSession = this.sessions[0]
              this.renderMessages()
            }
          } catch (error) {
            console.error('删除会话失败:', error)
            this.$message.error('删除会话失败')
          }
        })
        .catch(() => {
          this.$message.info('已取消删除')
        })
    },

    // 清空所有会话
    async clearAllSessions() {
      this.$confirm('确定要清空所有会话吗？此操作不可恢复。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        closeOnClickModal: false,
      })
        .then(async () => {
          try {
            await this.$http.delete('/api/sessions/clear')
            this.sessions = []
            this.currentSessionId = null
            this.currentSession = null
            this.clearMessages()
            await this.createNewSession()
          } catch (error) {
            console.error('清空会话失败:', error)
            this.$message.error('清空会话失败')
          }
        })
        .catch(() => {
          this.$message.info('已取消清空')
        })
    },

    // 导出会话
    async exportSessions() {
      try {
        const response = await this.$http.get('/api/sessions')
        if (response) {
          const sessions = response
          const dataStr = JSON.stringify(sessions, null, 2)
          const dataBlob = new Blob([dataStr], { type: 'application/json' })

          const url = URL.createObjectURL(dataBlob)
          const link = document.createElement('a')
          link.href = url
          link.download = `sessions_${
            new Date().toISOString().split('T')[0]
          }.json`
          link.click()

          URL.revokeObjectURL(url)
        }
      } catch (error) {
        console.error('导出会话出错:', error)
        this.$message.error('导出会话失败')
      }
    },

    // 渲染消息
    renderMessages() {
      if (
        this.currentSession &&
        this.currentSession.messages &&
        this.currentSession.messages.length > 0
      ) {
        this.messages = this.currentSession.messages
      } else {
        // 生成唯一id的欢迎消息
        const messageId =
          'session_' +
          Date.now() +
          '_' +
          Math.random().toString(36).substr(2, 9)

        this.messages = [
          {
            id: messageId,
            content:
              '您好！我是您的文档撰写助手。请选择一个知识库，然后输入您的问题。',
            sender: 'ai',
            timestamp: new Date().toISOString(),
          },
        ]
      }
      this.scrollToBottom()
    },

    // 清空消息
    clearMessages() {
      // 生成唯一id的欢迎消息
      const messageId =
        'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)

      this.messages = [
        {
          id: messageId,
          content:
            '您好！我是您的文档撰写助手。请选择一个知识库，然后输入您的问题。',
          sender: 'ai',
          timestamp: new Date().toISOString(),
        },
      ]
    },

    // 标签切换
    switchTab(tab) {
      this.activeTab = tab
      this.init()
      if (tab === 'sessions' && this.sessions.length === 0) {
        this.createNewSession()
      }
    },

    // 选择助手
    selectAssistant(assistantId) {
      // this.selectedAssistant = assistantId
      this.switchTab('sessions')

      // 创建新会话以刷新内容区域
      // this.createNewAssistantSession(assistantId)
    },

    // 创建助手特定的新会话
    async createNewAssistantSession(assistantId) {
      const sessionId = this.generateSessionId()
      const assistant = this.assistants.find((a) => a.id === assistantId)
      const welcomeMessage = this.getAssistantWelcomeMessage(assistantId)

      const newSession = {
        id: sessionId,
        title: '与' + (assistant ? assistant.name : '助手') + '的新会话',
        messages: [
          {
            id: this.generateMessageId(),
            content: welcomeMessage,
            sender: 'ai',
            timestamp: new Date().toISOString(),
          },
        ],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
        assistantId: assistantId,
      }

      try {
        await this.$http.post('/api/sessions', newSession)
        this.sessions.unshift(newSession)
        this.currentSessionId = sessionId
        this.currentSession = newSession
        this.messages = [...newSession.messages]
        this.scrollToBottom()
      } catch (error) {
        console.error('创建助手会话失败:', error)
        this.$message.error('切换助手失败')
        // 如果创建失败，至少在本地显示欢迎消息
        this.messages = [
          {
            id: this.generateMessageId(),
            content: welcomeMessage,
            sender: 'ai',
            timestamp: new Date().toISOString(),
          },
        ]
      }
    },

    // 获取助手的欢迎消息
    getAssistantWelcomeMessage(assistantId) {
      const welcomeMessages = {
        document:
          '您好！我是您的文档撰写助手。请选择一个知识库，然后输入您的问题。',
        agent:
          '您好！我是您的智能体助手。我可以帮助您完成各种任务，请告诉我您需要什么帮助。',
      }
      return (
        welcomeMessages[assistantId] ||
        '您好！我是您的AI助手。有什么可以帮助您的吗？'
      )
    },

    // 生成消息ID
    generateMessageId() {
      return (
        'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
      )
    },

    // 加载知识库列表
    async loadKnowledgeBases() {
      try {
        const response = await this.$http.get('/get-knowledge-bases')
        this.knowledgeBases = response || [
          { id: 'default', name: '默认知识库' },
        ]
      } catch (error) {
        console.error('加载知识库失败:', error)
        this.knowledgeBases = [{ id: 'default', name: '默认知识库' }]
      }
    },

    // 切换下拉菜单
    toggleDropdown(dropdown) {
      if (this.openDropdown === dropdown) {
        this.openDropdown = null
      } else {
        this.openDropdown = dropdown
      }
    },

    // 关闭所有下拉菜单
    closeAllDropdowns() {
      this.openDropdown = null
    },

    // 阻止下拉菜单点击事件冒泡到document
    preventClose(event) {
      event.stopPropagation()
    },

    // 选择知识库
    selectKnowledgeBase(id, name) {
      this.knowledgeBase = id
      this.knowledgeBaseName = name
      this.openDropdown = null
    },

    // 获取知识库名称
    getKnowledgeBaseName(id) {
      const kb = this.knowledgeBases.find((k) => k.id === id)
      return kb ? kb.name : '知识库选择'
    },

    // 选择模型
    selectModel(value, label) {
      this.llmModel = value
      this.modelName = label
      this.openDropdown = null
    },

    // 获取模型名称
    getModelName(value) {
      const model = this.llmModels.find((m) => m.value === value)
      return model ? model.label : '模型选择'
    },

    // 选择搜索方式
    selectSearchMode(value, label) {
      this.searchMode = value
      this.searchModeName = label
      this.openDropdown = null
    },

    // 获取搜索方式名称
    getSearchModeName(value) {
      const mode = this.searchModes.find((m) => m.value === value)
      return mode ? mode.label : '搜索方式'
    },

    // 处理文件上传
    handleFileUpload(event) {
      const files = event.target.files
      if (files.length === 0) return

      // 检查文件是否重复并添加新文件
      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        const isDuplicate = this.selectedFiles.some((f) => f.name === file.name)

        if (!isDuplicate) {
          this.selectedFiles.push(file)
        }
      }

      // 更新textarea显示
      this.updateTextareaWithFiles()

      // 重置文件输入，允许重新选择相同的文件
      event.target.value = ''
    },

    // 更新textarea中的文件显示
    updateTextareaWithFiles() {
      // 提取纯文本内容（不包含文件列表）
      const textLines = this.question
        .split('\n')
        .filter((line) => !line.startsWith('📎 '))
      const plainText = textLines.join('\n')

      // 重建textarea内容，添加文件列表
      let newTextareaValue = plainText

      // if (this.selectedFiles.length > 0 && plainText.trim()) {
      //   newTextareaValue += '\n'
      // }

      // if (this.selectedFiles.length > 0) {
      //   newTextareaValue +=
      //     '📎 ' + this.selectedFiles.map((file) => file.name).join('\n📎 ')
      // }

      this.question = newTextareaValue
    },

    // 删除文件
    deleteFile(index) {
      if (index >= 0 && index < this.selectedFiles.length) {
        // 从数组中移除文件
        this.selectedFiles.splice(index, 1)

        // 更新textarea显示
        this.updateTextareaWithFiles()
      }
    },

    // 发送问题
    async sendQuestion() {
      const question = this.question.trim()
      if (!question && this.selectedFiles.length === 0) {
        this.$message.warning('请输入您的问题或上传文件')
        return
      }

      // 检查是否有可用的会话
      if (!this.sessions || this.sessions.length === 0) {
        this.$message.error('没有可用的会话，请先创建会话')
        this.isTyping = false
        return
      }

      // 清空输入框
      this.question = ''

      // 添加用户消息 - 添加前检查是否已经存在相同内容和时间戳的消息
      const messageExists = this.messages.some(
        (m) =>
          m.sender === 'user' &&
          m.content === question &&
          Math.abs(new Date(m.timestamp) - new Date()) < 1000
      )

      if (!messageExists) {
        await this.addMessageToSession(question, 'user')
      }

      // 显示正在输入的状态
      this.isTyping = true

      try {
        // 检查是否有选择的文件
        if (this.selectedFiles.length > 0) {
          // 创建FormData对象来同时发送文本和文件
          const formData = new FormData()
          formData.append('question', question)
          formData.append('knowledge_base', this.knowledgeBase)
          formData.append('llm_model', this.llmModel)
          formData.append('search_mode', this.searchMode)
          formData.append('session_id', this.sessions[0].id)

          // 添加所有选择的文件
          this.selectedFiles.forEach((file, index) => {
            formData.append(`file_${index}`, file)
          })

          // 发送FormData请求
          const response = await this.$http.post(
            '/query_with_files',
            formData,
            {
              headers: {
                'Content-Type': 'multipart/form-data',
              },
            }
          )

          // 处理响应
          await this.processResponse(response)

          // 发送成功后清空已选择的文件
          this.selectedFiles = []
        } else {
          // 只发送文本问题
          const response = await this.$http.post('/query', {
            question: question,
            knowledge_base: this.knowledgeBase,
            llm_model: this.llmModel,
            search_mode: this.searchMode,
            session_id: this.sessions[0].id,
          })

          // 处理响应
          await this.processResponse(response)
        }
      } catch (error) {
        console.error('发送问题失败:', error)
        await this.addMessageToSession(
          `抱歉，网络请求失败: ${error.message || '未知错误'}`,
          'ai'
        )
      } finally {
        // 隐藏正在输入的状态
        this.isTyping = false
        // 清空文件列表
        this.selectedFiles = []
      }
    },

    // 处理响应 - 统一处理各种类型的AI回复
    async processResponse(data) {
      // 移除"正在输入..."消息
      this.removeTypingMessage()

      if (data.success) {
        let answerContent = data.answer

        // 添加优化建议
        if (data.optimization_tips && data.optimization_tips.length > 0) {
          let tipsHtml = '<div class="optimization-tips">'
          tipsHtml +=
            '<strong><i class="fas fa-lightbulb"></i> 优化建议:</strong>'
          tipsHtml += '<ul>'
          data.optimization_tips.forEach((tip) => {
            tipsHtml += `<li>${tip}</li>`
          })
          tipsHtml += '</ul></div>'
          answerContent += tipsHtml
        }

        // 检查是否是重复的AI回复
        const twoSecondsAgo = Date.now() - 2000
        const lastAIMessage = this.messages[this.messages.length - 1]
        let isDuplicate = false

        if (lastAIMessage && lastAIMessage.sender === 'ai') {
          const lastMessageTime = new Date(lastAIMessage.timestamp).getTime()
          // 简单比较内容，忽略可能的格式差异
          const simplifiedContent = answerContent.replace(/<[^>]*>/g, '')
          const simplifiedLastContent = lastAIMessage.content.replace(
            /<[^>]*>/g,
            ''
          )
          isDuplicate =
            lastMessageTime > twoSecondsAgo &&
            simplifiedContent === simplifiedLastContent
        }

        if (!isDuplicate) {
          // 使用addMessageToSession方法添加消息，该方法已包含唯一ID生成和重复检查
          await this.addMessageToSession(answerContent, 'ai')
        }
      } else {
        const errorMessage = `抱歉，处理您的问题时出错: ${
          data.error || '未知错误'
        }`
        await this.addMessageToSession(errorMessage, 'ai')
      }
    },

    // 移除正在输入的提示消息
    removeTypingMessage() {
      // 设置isTyping状态为false，控制UI显示
      this.isTyping = false

      // 如果有特殊的正在输入提示消息元素，可以在这里清除
      // 由于代码中没有明确的typing message元素，这里只设置状态
    },

    // 清空窗口
    clearWindow() {
      this.clearMessages()
    },

    // 清除上下文
    async clearContext() {
      try {
        const response = await this.$http.post('/clear-context')

        // 生成唯一时间戳
        const timestamp =
          new Date().toISOString() +
          '-' +
          Math.random().toString(36).substr(2, 5)

        let messageContent = ''

        if (response.success) {
          messageContent = '对话上下文已清除。'
        } else {
          messageContent = `清除上下文失败: ${response.error}`
        }

        // 创建消息对象
        const message = {
          content: messageContent,
          sender: 'ai',
          timestamp: timestamp,
        }

        // 直接添加到本地消息数组，避免经过addMessageToSession的复杂逻辑
        // 以防止潜在的重复渲染
        this.messages.push(message)

        // 滚动到底部
        this.scrollToBottom()
      } catch (error) {
        console.error('清除上下文失败:', error)

        // 生成唯一时间戳
        const timestamp =
          new Date().toISOString() +
          '-' +
          Math.random().toString(36).substr(2, 5)

        // 直接添加错误消息到本地数组
        this.messages.push({
          content: `清除上下文失败: ${error.message}`,
          sender: 'ai',
          timestamp: timestamp,
        })

        // 滚动到底部
        this.scrollToBottom()
      }
    },

    // 复制到剪贴板
    copyToClipboard(content) {
      // 提取纯文本内容（移除HTML标签）
      const tempDiv = document.createElement('div')
      tempDiv.innerHTML = content
      const plainText = tempDiv.textContent || tempDiv.innerText || ''

      // 复制到剪贴板
      navigator.clipboard
        .writeText(plainText)
        .then(() => {
          // 显示复制成功提示
          this.showCopyToast = true
          setTimeout(() => {
            this.showCopyToast = false
          }, 2000)
        })
        .catch((error) => {
          console.error('复制失败:', error)
          this.$message.error('复制失败')
        })
    },

    // 显示导出模态框
    showExportModal(content) {
      this.exportContent = content
      this.showExportModalFlag = true
    },

    // 关闭导出模态框
    closeExportModal() {
      this.showExportModalFlag = false
    },

    // 确认导出
    async confirmExport() {
      // 获取要导出的内容
      const content = this.exportContent

      // 提取纯文本内容
      const tempDiv = document.createElement('div')
      tempDiv.innerHTML = content
      const plainText = tempDiv.textContent || tempDiv.innerText || ''

      try {
        // 显示加载提示
        this.$message({ message: '正在生成保存文件...', type: 'info' })

        // 调用后端API进行导出
        const response = await this.$http.post('/api/export-document', {
          content: plainText,
          title: 'ai_response_' + new Date().toISOString().slice(0, 10),
          format: this.exportFormat,
        })

        if (response && response.success) {
          this.$message.success(`文档生成成功！保存路径：${response.file_path}`)
        } else {
          this.$message.error('文档生成失败，请重试。')
        }
      } catch (error) {
        console.error('生成文件时出错:', error)
        this.$message.error('文件导出失败，请重试。')
      } finally {
        // 关闭模态框
        this.closeExportModal()
      }
    },

    // 格式化会话时间
    formatSessionTime(timestamp) {
      const date = new Date(timestamp)
      const today = new Date()
      const isToday = date.toLocaleDateString() === today.toLocaleDateString()
      return isToday
        ? date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
        : date.toLocaleDateString()
    },

    // 滚动到底部
    scrollToBottom() {
      this.$nextTick(() => {
        const chatMessages = this.$refs.chatMessages
        if (chatMessages) {
          chatMessages.scrollTop = chatMessages.scrollHeight
        }
      })
    },

    // 渲染Markdown
    renderMarkdown(content) {
      try {
        // 检查内容是否已经是HTML格式，如果是则直接返回
        if (content && content.startsWith('<') && content.includes('>')) {
          return content
        }
        // 使用marked库渲染Markdown内容，设置选项允许HTML标签
        const html = marked.parse(content, {
          breaks: true, // 允许换行符转换为<br>
          gfm: true, // 启用GitHub风格的Markdown
          sanitize: false, // 不进行HTML标签过滤
        })
        return html
      } catch (error) {
        console.error('Markdown渲染失败:', error)
        // 如果渲染失败，回退到简单的换行处理
        return content.replace(/\n/g, '<br>')
      }
    },

    // 生成会话ID
    generateSessionId() {
      return (
        'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
      )
    },

    // 跳转到知识库管理
    goToKnowledgeBaseManager() {
      this.$router.push('/knowledge_bases')
    },
  },
}
</script>

<style>
/* 主容器样式 */
.app-container {
  display: flex;
  height: 100vh;
  width: 100%;
}

/* 侧边栏样式 */
.sidebar {
  width: 280px;
  background-color: #fff;
  border-right: 1px solid #e1e8ed;
  display: flex;
  flex-direction: column;
}

.sidebar-header {
  padding: 15px;
  border-bottom: 1px solid #e1e8ed;
  font-weight: bold;
  font-size: 1.2em;
  color: #2c3e50;
}

.tabs {
  display: flex;
  border-bottom: 1px solid #e1e8ed;
}

.tab {
  padding: 12px 20px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all 0.3s;
}

.tab.active {
  border-bottom: 2px solid #3498db;
  color: #3498db;
  font-weight: 500;
}

.tab-content {
  flex-grow: 1;
  overflow-y: auto;
  padding: 15px;
}

/* 助手项样式 */
.assistant-item {
  padding: 12px 15px;
  border-radius: 6px;
  cursor: pointer;
  margin-bottom: 8px;
  transition: background-color 0.2s;
}

.assistant-item:hover {
  background-color: #f5f7fa;
}

.assistant-item.selected {
  background-color: #e3f2fd;
  color: #3498db;
}

/* 会话列表样式 */
.session-list {
  padding: 0;
  margin: 0;
  list-style: none;
  max-height: calc(100vh - 200px);
  overflow-y: auto;
}

.session-item {
  padding: 12px 15px;
  border-radius: 6px;
  cursor: pointer;
  margin-bottom: 8px;
  transition: all 0.2s;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid transparent;
  position: relative;
}

.session-item:hover {
  background-color: #f5f7fa;
  border-color: #e1e8ed;
}

.session-item.active {
  background-color: #e3f2fd;
  color: #3498db;
  border-color: #3498db;
}

.delete-session-btn {
  background: none;
  border: none;
  color: #999;
  cursor: pointer;
  padding: 5px;
  border-radius: 3px;
  transition: all 0.2s;
  opacity: 0;
}

.session-item:hover .delete-session-btn {
  opacity: 1;
}

.delete-session-btn:hover {
  color: #e74c3c;
  background-color: #ffebee;
}

/* 会话操作区域 */
.session-actions {
  display: flex;
  gap: 8px;
  padding: 12px;
  align-items: center;
  justify-content: start;
  flex-wrap: nowrap;
}

.session-actions .control-button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 10px;
  font-size: 0.85em;
  min-width: 40px;
  height: 32px;
}

.session-actions .new-session-btn {
  height: 32px;
  align-items: center;
  justify-content: center;
}

/* 新会话按钮 */
.new-session-btn {
  background-color: #3498db;
  color: white;
  padding: 6px 12px;
  border: none;
  border-radius: 15px;
  cursor: pointer;
  font-size: 0.85em;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.new-session-btn:hover {
  background-color: #2980b9;
}

/* 主内容区域 */
.main-content {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  border: 1px solid #e1e8ed;
  border-radius: 8px;
  overflow: hidden;
}

/* 聊天消息区域 */
.chat-messages {
  display: flex;
  flex-direction: column;
  padding: 20px;
  background-color: #f8f9fa;
  flex-grow: 1;
  overflow-y: auto;
  min-height: 0;
}

.message {
  margin-bottom: 15px;
  padding: 10px 15px;
  border-radius: 8px;
  max-width: 80%;
}

.user-message {
  background-color: #f5f5f5;
  margin-left: auto;
}

.ai-message {
  background-color: #f8f9fa;
}

.message-header {
  font-weight: bold;
  margin-bottom: 5px;
  display: flex;
  align-items: center;
  gap: 5px;
}

.message-content {
  word-wrap: break-word;
  line-height: 1.6;
}

/* Markdown样式增强 */
.message-content h1,
.message-content h2,
.message-content h3,
.message-content h4,
.message-content h5,
.message-content h6 {
  margin-top: 16px;
  margin-bottom: 8px;
  font-weight: 600;
  line-height: 1.25;
}

.message-content h1 {
  font-size: 1.8em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.message-content h2 {
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.message-content h3 {
  font-size: 1.25em;
}

.message-content h4 {
  font-size: 1em;
}

.message-content ul,
.message-content ol {
  padding-left: 2em;
  margin: 8px 0;
}

.message-content li {
  margin-bottom: 4px;
}

.message-content code {
  background-color: #f6f8fa;
  border-radius: 3px;
  padding: 0.2em 0.4em;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 85%;
}

.message-content pre {
  background-color: #f6f8fa;
  border-radius: 3px;
  padding: 16px;
  overflow: auto;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 85%;
  margin: 16px 0;
}

.message-content pre code {
  background-color: transparent;
  padding: 0;
}

.message-content blockquote {
  border-left: 4px solid #dfe2e5;
  color: #6a737d;
  padding: 0 1em;
  margin: 16px 0;
}

.message-content a {
  color: #0366d6;
  text-decoration: none;
}

.message-content a:hover {
  text-decoration: underline;
}

.message-content p {
  margin: 8px 0;
}

.message-content img {
  max-width: 100%;
  height: auto;
  border-radius: 4px;
}

.message-content hr {
  border: 0;
  height: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
  margin: 20px 0;
}

/* 用户消息的特殊样式调整 */
.user-message .message-content code,
.user-message .message-content pre {
  background-color: rgba(255, 255, 255, 0.2);
}

.user-message .message-content a {
  color: #e6f7ff;
  text-decoration: underline;
}

/* AI消息的特殊样式调整 */
.ai-message .message-content a:hover {
  text-decoration: underline;
}

.message-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid #e0e0e0;
}

/* 聊天输入区域 */
.chat-input {
  /* display: flex;
  flex-direction: column; */
  padding: 15px;
  border-top: 1px solid #e1e8ed;
  background-color: #fff;
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}

.text-area-container {
  position: relative;
  margin-bottom: 15px;
}

textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  resize: none;
  height: 100px;
  box-sizing: border-box;
}

/* 文件列表样式 */
.file-list-container {
  border: 1px solid #ddd;
  border-radius: 4px;
  margin-bottom: 10px;
  background-color: #f9f9f9;
}

.file-list-header {
  padding: 8px 12px;
  font-weight: bold;
  border-bottom: 1px solid #ddd;
  background-color: #f0f0f0;
}

.file-list-items {
  max-height: 150px;
  overflow-y: auto;
}

.file-item {
  padding: 8px 12px;
  border-bottom: 1px solid #eee;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-item:last-child {
  border-bottom: none;
}

.file-name {
  flex-grow: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.delete-file-btn {
  background: none;
  border: none;
  color: #dc3545;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.delete-file-btn:hover {
  background-color: rgba(220, 53, 69, 0.1);
}

/* 输入控制区域 */
.input-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* 下拉菜单 */
.dropdown-container {
  position: relative;
}

.dropdown-button {
  background-color: #f8f9fa;
  color: #333;
  padding: 8px 20px 8px 10px;
  border: 1px solid #ccc;
  border-radius: 15px;
  cursor: pointer;
  font-size: 0.9em;
  position: relative;
  min-width: 80px;
  width: auto;
  white-space: nowrap;
  text-align: left;
}

.dropdown-button:after {
  content: '▲';
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.7em;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: white;
  min-width: 120%;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  z-index: 9999;
  max-height: 200px;
  overflow-y: auto;
  bottom: 100%;
  top: auto;
  margin-bottom: 5px;
  pointer-events: auto;
}

.dropdown-container.active .dropdown-content {
  display: block;
}

.dropdown-item {
  padding: 12px 20px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.dropdown-item:hover {
  background-color: #e9ecef;
}

/* 按钮样式 */
.control-button {
  background-color: #f8f9fa;
  color: #333;
  padding: 8px 15px;
  border: 1px solid #ccc;
  border-radius: 15px;
  cursor: pointer;
  font-size: 0.9em;
}

.control-button:hover {
  background-color: #e9ecef;
}

.upload-button {
  background-color: #4caf50;
  color: white;
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9em;
}

.upload-button:hover {
  background-color: #388e3c;
}

.send-button {
  background-color: #3498db;
  color: white;
  padding: 8px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9em;
  margin-left: auto;
}

.send-button:hover {
  background-color: #2980b9;
}

.file-upload {
  display: none;
}

/* 功能按钮组 */
.function-buttons {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  padding-left: 20px;
  border-left: 1px solid #e1e8ed;
}

.function-buttons .control-button,
.function-buttons .upload-button,
.function-buttons .send-button {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 1.1em;
  border-radius: 50%;
}

/* 图标按钮 */
.icon-button {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 15px;
  cursor: pointer;
  position: relative;
  border: 1px solid #ccc;
  background-color: #f8f9fa;
  color: #333;
  font-size: 14px;
  transition: all 0.2s ease;
}

/* 复制和下载按钮特定样式 */
.message-actions .icon-button {
  width: 24px;
  height: 24px;
  font-size: 12px;
  border-color: #e0e0e0;
}

.message-actions .icon-button:hover {
  background-color: #e9ecef;
  border-color: #adb5bd;
  transform: translateY(-1px);
}

/* 复制成功提示 */
.copy-success-toast {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 12px 24px;
  border-radius: 6px;
  font-size: 14px;
  z-index: 10000;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.copy-success-toast.show {
  opacity: 1;
  visibility: visible;
}

/* 工具提示 */
.tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s, visibility 0.3s;
  margin-bottom: 5px;
  z-index: 1000;
}

/* 优化建议样式 */
.optimization-tips {
  margin-top: 15px;
  padding: 12px;
  background-color: #fff3cd;
  border-left: 4px solid #ffc107;
  border-radius: 4px;
  font-size: 0.9em;
}

.optimization-tips strong {
  color: #856404;
  display: block;
  margin-bottom: 8px;
}

.optimization-tips ul {
  margin: 0;
  padding-left: 20px;
  color: #856404;
}

.optimization-tips li {
  margin-bottom: 4px;
}

/* 引用来源样式 */
.citation {
  display: inline-block;
  background-color: #e9ecef;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.8em;
  color: #495057;
  margin: 0 2px;
}

/* 模态框样式 */
.modal {
  position: fixed;
  z-index: 1000;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
  background-color: #fff;
  margin: 15% auto;
  padding: 20px;
  border: 1px solid #888;
  border-radius: 8px;
  width: 300px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e1e8ed;
}

.modal-title {
  margin: 0;
  font-size: 1.2em;
  color: #2c3e50;
}

.close-btn {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
}

.close-btn:hover,
.close-btn:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}

.format-options {
  margin-bottom: 20px;
}

.format-option {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  padding: 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.format-option:hover {
  background-color: #f5f7fa;
}

.format-option input[type='radio'] {
  margin-right: 10px;
}

.format-option label {
  cursor: pointer;
  margin: 0;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 15px;
  border-top: 1px solid #e1e8ed;
}

.modal-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.confirm-btn {
  background-color: #3498db;
  color: white;
}

.confirm-btn:hover {
  background-color: #2980b9;
}

.cancel-btn {
  background-color: #e74c3c;
  color: white;
}

.cancel-btn:hover {
  background-color: #c0392b;
}
</style>
